import math
import requests
import json
import pandas as pd
import folium
from folium.plugins import *
import os

apikey = 'e12dac77a7d1485a158f7555868b5dc7'
# 在代码顶部定义固定颜色列表（25种不同颜色，兼容Matplotlib和Folium）
FIXED_COLORS = [
    # 高亮颜色（替换高德相似色）
    '#9400D3',  # 深紫色
    '#FF1493',  # 深粉色（替代蓝色）
    '#32CD32',  # LimeGreen（替代绿色）
    '#DA70D6',  # 紫罗兰（替代紫色）

    # 高对比度颜色
    '#FF4500',  # 橙红色
    '#00FF00',  # 荧光绿
    '#FF69B4',  # 热粉色
    '#7FFF00',  # 黄绿色

    # 扩展颜色
    '#8A2BE2',  # 蓝紫色
    '#DC143C',  # 深红色
    '#20B2AA',  # 浅海绿
    '#FF6347',  # 番茄红
    '#BA55D3',  # 中紫色

    # 更多独特颜色
    '#00FA9A',  # 中春绿色
    '#6A5ACD',  # 石板蓝
    '#FF8C00',  # 暗橙色
    '#3CB371',  # 中海绿
    '#DAA520',  # 金色

    # 补充颜色
    '#48D1CC',  # 中绿松石
    '#C71585',  # 中紫红
    '#ADFF2F',  # 绿黄色
    '#FF00FF',  # 品红
    '#4B0082'  # 靛蓝色
]

def route_planning(apikey, origin, destination, waypoints):
    '''
    调用高德接口实现驾车路径规划
    '''
    url = "https://restapi.amap.com/v3/direction/driving"
    parameters = {'key': apikey,
                  'origin': origin,  # 起点
                  'destination': destination,  # 终点
                  'strategy': 0,  # 策略
                  'waypoints': waypoints,  # 途经点
                  'ferry': 1,  # 不使用渡轮
                  'extensions': 'all',  # 返回全部信息
                  'output': 'JSON',  # 输出格式
                  }
    response = requests.get(url, params=parameters)
    data = json.loads(response.text)
    if data['info'] == 'OK':
        distance = data['route']['paths'][0]['distance']  # 距离（米）
        tolls = data['route']['paths'][0]['tolls']  # 总费用（元）

        polyline = ""
        for step in data['route']['paths'][0]['steps']:
            polyline = polyline + (';' if polyline else "") + step['polyline']  # 途经点拼接，后面要去重
        point_list = []
        _ = [point_list.append(i) for i in polyline.split(';') if not i in point_list]  # 去重
        return distance, tolls, [i.split(',') for i in point_list]
    else:
        print('接口报错')
        return [None] * 3

def gcj02_to_wgs84(lng, lat):
    """
    将GCJ-02坐标转换为WGS-84坐标
    """
    a = 6378245.0
    ee = 0.00669342162296594323
    dLat = transform_lat(lng - 105.0, lat - 35.0)
    dLng = transform_lng(lng - 105.0, lat - 35.0)
    radLat = lat / 180.0 * math.pi
    magic = math.sin(radLat)
    magic = 1 - ee * magic * magic
    sqrtMagic = math.sqrt(magic)
    dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * math.pi)
    dLng = (dLng * 180.0) / (a / sqrtMagic * math.cos(radLat) * math.pi)
    mgLat = lat + dLat
    mgLng = lng + dLng
    return [lng * 2 - mgLng, lat * 2 - mgLat]


def transform_lat(lng, lat):
    """
    纬度转换
    """
    ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))
    ret += (20.0 * math.sin(6.0 * lng * math.pi) + 20.0 * math.sin(2.0 * lng * math.pi)) * 2.0 / 3.0
    ret += (20.0 * math.sin(lat * math.pi) + 40.0 * math.sin(lat / 3.0 * math.pi)) * 2.0 / 3.0
    ret += (160.0 * math.sin(lat / 12.0 * math.pi) + 320 * math.sin(lat * math.pi / 30.0)) * 2.0 / 3.0
    return ret


def transform_lng(lng, lat):
    """
    经度转换
    """
    ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))
    ret += (20.0 * math.sin(6.0 * lng * math.pi) + 20.0 * math.sin(2.0 * lng * math.pi)) * 2.0 / 3.0
    ret += (20.0 * math.sin(lng * math.pi) + 40.0 * math.sin(lng / 3.0 * math.pi)) * 2.0 / 3.0
    ret += (150.0 * math.sin(lng / 12.0 * math.pi) + 300.0 * math.sin(lng / 30.0 * math.pi)) * 2.0 / 3.0
    return ret


def wgs84_to_mercator(lng, lat):
    """
    将WGS-84坐标转换为Mercator投影
    """
    x = lng * 20037508.34 / 180
    y = math.log(math.tan((90 + lat) * math.pi / 360)) / (math.pi / 180)
    y = y * 20037508.34 / 180
    return round(x / 1000, 2), round(y / 1000, 2)


def gcj02_to_mercator(lng, lat):
    '''
    高德经纬度转换为mercator坐标
    '''
    lng = float(lng)
    lat = float(lat)
    wgs84_coordinates = gcj02_to_wgs84(lng, lat)
    return wgs84_to_mercator(*wgs84_coordinates)

def get_unique_filename(directory, filename):
    # 分离文件名和扩展名
    name, ext = os.path.splitext(filename)
    counter = 1
    new_filename = filename

    # 检查文件是否存在，如果存在则添加编号
    while os.path.exists(os.path.join(directory, new_filename)):
        new_filename = f"{name}_{counter}{ext}"
        counter += 1
    return new_filename

'''生成gps高德路径轨迹图'''
def draw_gps(customer_list, gLine_car, base_name, decide):
    df = pd.DataFrame(customer_list)
    station = customer_list[20]['coordinate'] # 设置生成的gps路径地图的默认中心
    station_lon_lat = str(station[0]) + ',' + str(station[1])

    # 画图
    if decide == 0 :
        tiles = 'https://wprd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=6' # 6：卫星地图；7：正常地图； 8：灰度地图
    elif decide == 1:
        tiles = 'https://wprd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7' # 6：卫星地图；7：正常地图； 8：灰度地图
    else:
        tiles = 'https://wprd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=8' # 6：卫星地图；7：正常地图； 8：灰度地图
    m = folium.Map([station[1], station[0]],  # 中心区域的确定
                   tiles=tiles,
                   zoom_start=11, # 地图缩放级别默认值为10，值越大越清晰
                   control_scale=True,
                   attr='高德-常规图')
    route_info = []

    for i in range(len(gLine_car)):
        line = gLine_car[i][1:-1]
        waypoints = ""
        for cid in line:
            lon_lat = df[df.customer_id == cid].coordinate.iloc[0]
            waypoints += (str(lon_lat[0]) + ',' + str(lon_lat[1]) + ';')
        waypoints = waypoints[:-1]
        distance, tolls, points = route_planning(apikey, station_lon_lat, station_lon_lat, waypoints)
        route_info.append([distance, tolls, gLine_car[i]])
        points = [[float(p[1]), float(p[0])] for p in points]

        PolyLineOffset(points,
                       weight=6,  # 线的大小6
                       color=FIXED_COLORS[i],  # 线的颜色
                       opacity=1,  # 设置线的透明度 1：不透明 0：完全透明
                       offset= i - (i - 0.5)  # 设置偏移量，防止线重叠在一起
                       ).add_to(m)  # 将这条线添加到刚才的区域m内
    # 起始点，结束点
    for li in customer_list:
        location = li['coordinate']
        folium.Marker([location[1], location[0]], popup='<b>{}</b>'.format(li['name'])).add_to(m)

    html_filename = get_unique_filename('./gd/save/', base_name)
    m.save(os.path.join('../gd/save/', html_filename))  # 将结果以HTML形式保存到指定路径
    return route_info